# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter


# 这个文件内的所有 管道 都是想通的

# 当在 settings.py 中打开管道后，管道会在爬虫文件之前打开，一直处于打开状态，直到程序结束
# 所以 存储文件 只要一开始打开就不会突然关闭
class DangdangPipeline:
	# 该函数名是固定的
	# 在爬虫文件之前打开 存储数据 的文件
	# open_spider() 在管道打开的同时就会执行，之后一直处于打开状态，直到遇到 close_spider()
	def open_spider(self, spider):
		# 先将文件打开，等待数据的写入，所以打开方式可以为 w，不怕被覆盖，因为一直处于打开状态。
		# 只有关闭了再打开才会覆盖数据
		# 使用 类的 self 是为了让 file 能够在不同函数中使用
		self.file = open('book.json', 'w', encoding='utf-8')

	# item 是 parse() 返回的列表中一个又一个数据，即列表的一个一个的列表元素
	# item 的数据类型 根据 parse() 返回的 数据 的类型决定，这里是字典
	# 也就是说，process_item() 会自动遍历 parse() 返回的列表对象，然后将数据（列表元素）一个一个地赋值给 item
	def process_item(self, item, spider):
		# 将数据存入文件中
		# 打开方式为“a”，因为是追加写入，不然会被覆盖
		# 这里会频繁打开文件，有些不友好。每次传输数据过来就打开一次
		# 思考？能否让文件一直打开，直到数据全部传输完才关闭？
		# with open('book.json','a',encoding='utf-8') as file:
		#     file.write(str(item))

		# 只要 parse() 有数据返回，process_item() 就会一直执行
		# 等无数据返回，该函数才会停止，如此后面的关闭文件函数才会执行
		# 不用怕文件突然关闭的问题
		self.file.write(str(item))

		return item

	# 等数据全部返回过来，并写入文件后，该函数才会执行
	# 等爬虫文件结束后才执行
	# 关闭存储文件
	def close_spider(self, spider):
		self.file.close()


import urllib.request


# 自定义管道类，让其专门下载书籍图片，或做与上面管道不同的功能
# 定义好管道后，需要在 setting.py 中添加“权限”
class DangdangDownloadPipelin(object):
	# 这个函数必须与上面主管道的相同，完全相同
	# item 就是 parse() 中的字典
	def process_item(self, item, spider):
		src = item.get('src')
		name = item.get('name')

		urllib.request.urlretrieve(url=src, filename='./book/{}.jpg'.format(name))

		return item
